﻿// See https://aka.ms/new-console-template for more information
using Gasgoo.CacheProvider.BySqlServe;
using Gasgoo.DataProvider.ByEntityFramework;
using Gasgoo.DataProvider.BySqlSugar;
using Gasgoo.DataProvider.EntityFramework.iToolLogger;
using Gasgoo.DataProvider.SqlSugar;
using Gasgoo.QueueProvider;
using Gasgoo.ShareLibrary.Framework;
using Gasgoo.ShareLibrary.Framework.Global;
using Gasgoo.ShareLibrary.Framework.Options;
using iToolLogger.Query.Interface;
using IToolLogger.Interface;
using Microsoft.Extensions.DependencyInjection;
using Orleans.Runtime;
using Serilog;
using Serilog.Events;
using Serilog.Sinks.Grafana.Loki;
using SqlSugar;

Console.WriteLine("Hello, World!");

// 测试：泛型服务接口，隐士订阅，队列服务设计（成功|失败|重试）

// cache
// queue
// db + ef（test）
// 计划任务
// logger


// 定义 各种存储(mssql/mongo) Provider 和内存

//var context = new iToolLoggerContext();
//context.Database.EnsureCreated();

var hostBuild = new GasgooHostBuilder();

// 配置集群
hostBuild.UseAdoNetClustering(new AdoNetClusterOptions
{
    AdoNetOptions = new AdoNetOptions
    {
        DataSource = "10.0.1.9",
        UID = "Gas_News",
        PWD = "QGsga*!H0B1QXfPTo%tfNcc3e"
    },
    ResponseTimeout = TimeSpan.FromSeconds(15)
});

// 配置 logger
{
    List<LokiLabel> labels = new List<LokiLabel>
    {
        new LokiLabel { Key = "namespace", Value = "Gasgoo" },
        new LokiLabel { Key = "app", Value = "QuickStart" },
    };

    Log.Logger = new LoggerConfiguration()
                     .Enrich.FromLogContext()
                    .WriteTo.Console()
                   //过滤Net Core系统日志
                   .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
                   .MinimumLevel.Override("Yarp", LogEventLevel.Warning)
                   .MinimumLevel.Override("Orleans", LogEventLevel.Warning)
                   //Loki地址配置信息 
                   .WriteTo.GrafanaLoki("http://loki.tools.gasgoo.com", labels)
                   .CreateLogger();

    hostBuild.ConfigureLogging(logging => logging.AddSerilog(Log.Logger));
}

// 注册公有服务
{
    hostBuild.ConfigureServices(s =>
    {
        s.AddDbContext<iToolLoggerContext>();
    });
}

// 配置数据Provider { IDataStorageFactory }
{
    // ef 的
    hostBuild.UseGasgooStorage<DataStorageProviderByEntity>(Constants.DATA_ENTITY_PROVIDER);

    // sugar 的 { 多数据配置模式 }
    hostBuild.UseGasgooStorage<DataStorageProviderBySuagr>(
        Constants.DATA_SUGAR_PROVIDER,
        (n, s) =>
        {
            s.AddTransientNamedService<SqlSugarClient>(n, GasgooUtils.Create<SugarLoggerContext>);
        });

    //hostBuild.UseGasgooStorage<DataStorageProviderBySuagr>(
    //    Constants.DATA_SUGAR_PROVIDER + "Order",
    //    (n, s) =>
    //    {
    //        s.AddTransientNamedService(n, GasgooUtils.Create<SugarOrderContext>);
    //    });

    // cache -> sql 的
    hostBuild.UseGasgooStorage<SqlServerCacheStorageProvider>(Constants.CACHE_SQLSERVE_PROVIDER);
}

// 配置Stream provider { IQueueStorageFactory }
{
    hostBuild.UseStreamProvider<SQLServerQueueStorageProvider>(Constants.QUEUE_SQLSERVE_PROVIDER);
}

// 启动事件注册在这里
{
    hostBuild.AddStartupTask((s, ctx) =>
    {
        return Task.CompletedTask;
    });
}



// 启动服务
IClusterService cluster = await hostBuild.BuildAndStartAsync();

// 服务测试
{

    var logfn = cluster.GetService<ILogFunctionService>(3);
    var query = cluster.GetService<ILoggerOrderService>();

    // 表操作
    var res = await logfn.GetLogFunctionAsync();
    await logfn.ModifyAsync();
    res = await logfn.GetLogFunctionAsync();
    await logfn.ModifyAsync();


    var list = await logfn.QueryAsync();

    // 查询 { where page orderby group } Data 应该具备{执行sql, or lamda}的能力
    // var loggers = await query.GetLoggers();
    // loggers = await query.GetLoggers("6");

    var guid = GasgooUtils.ToGuid("testper");
    var queue = cluster.GetQueueProvider(Constants.QUEUE_SQLSERVE_PROVIDER);
    var stream = queue.GetStream<string>(guid, "order");


    int i = 0;
    while (true)
    {
        if (i > 3)
        {
            var val = Console.ReadLine();
        }
        ////await logfn.ModifyAsync();

        //if (string.IsNullOrEmpty(val))
        //    continue;

        //await Task.Delay(1000);

        i++;
        await stream.OnNextAsync($"val is {i} - {DateTime.Now}");
    }
}
